using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Neat;
using Neat.Components;
using Neat.Mathematics;
using Microsoft.Speech.Recognition;
using Neat.Graphics;

namespace RiverRaidX
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : NeatGame
    {
        public Game1() : base()
        {
            Window.Title = "River Raid X";
            //Console.Run("call startup.nsc");
        }
        //TrackHUD trackHUD;
        protected override void Initialize()
        {
            GameWidth = 1280;
            GameHeight = 720;
            StretchMode = StretchModes.Fit;
            
            ResizeToScreen();
            if (OutputResolution.Y >= 1080)
            {
                GameWidth = 1920;
                GameHeight = 1080;
            }
            base.Initialize();
            HasConsole = true;
            ConsoleKey = Keys.OemTilde;
            
            Console.AddCommand("g_start", NewGame);
            CalibrateScreen.ShowModeButtons = false;
            //Console.Run("dv e_music true");
            //Console.Run("dv rr_effects true");
            //MediaPlayer.Volume = 0f;

            ActiveScreen = "neatscreen";
        }

        void NewGame(IList<string> args)
        {
            ((RiverRaidGame)Screens["game"]).Reset();
            ActivateScreen("game");
        }

        public override void FirstTime()
        {
            base.FirstTime();
            Console.Run("g_reinit");
            Console.Run("m_gamescreen game");
            Console.Run("sh neatscreen");
            
            //Console.Run("sh startscreen");
            Console.AddCommand("e_playsongs", e_playsongs);
            ElegantTextEngine.Position = new Vector2(GameWidth, GameHeight) - new Vector2(600,200);

            DefaultTransition = new Neat.Transitions.Fader()
            {
                Length = new TimeSpan(0, 0, 0, 0, 500),
                Rate = 2.0f
            };
        }

        protected override void LoadContent()
        {
            ContentDuplicateBehavior = ContentDuplicateBehaviors.Replace;
            LoadTexture("Sprites\\menuBackground");
            LoadEffect(@"Effects\Fullscreen");
            LoadSong(@"Music\DST-Xmorph", "song1");
            LoadSong(@"Music\DST-MechaNoir", "song2");
            LoadSong(@"Music\Singaya_RatMonkey", "song3");
            LoadSong(@"Music\Blaster_Route909", "song4");
            MediaPlayer.MediaStateChanged += new EventHandler<EventArgs>(MediaPlayer_MediaStateChanged);

            base.LoadContent();

#if SPEECH
            try
            {
                Speech = new SpeechEngine(this);
                Components.Add(Speech);
                Speech.Initialize();
                Speech.AddChoice("bang");
                Speech.AddChoice("shoot");
                Speech.AddChoice("new game");
                Speech.AddChoice("start game");
                Speech.AddChoice("exit game");
                Speech.AddChoice("exit");
                Speech.AddChoice("quit");
                Speech.AddChoice("quit game");
                Speech.AddChoice("pause game");
                Speech.AddChoice("resume game");
                Speech.AddChoice("sound off");
                Speech.AddChoice("sound on");
                Speech.AddChoice("music off");
                Speech.AddChoice("music on");
                Speech.SpeechRecognizedFunc = SpeechRecognized;
                Speech.SpeechHypothesizedCommand = "rr_shoot";
                Speech.StartListening();
            }
            catch
            {
                Console.Run("et_echo Speech initialization failed.");
                Speech = null;
            }
#endif


            #if KINECT
                if (Kinect.ColorStream == null) Kinect.OpenColorStream();
                Kinect.Draw = true;
            #endif
        }

#if SPEECH
        void SpeechRecognized(SpeechRecognizedEventArgs e)
        {
            if (e.Result.Confidence > 0.90f)
            {
                Console.Run("et_echo " + e.Result.Text);
                if (ActiveScreen == "quitconfirm")
                {
                    if (e.Result.Text == "exit game" ||
                        e.Result.Text == "exit" ||
                        e.Result.Text == "quit") Console.Run("quit");
                    return;
                }

                if (e.Result.Text == "new game" || e.Result.Text == "start game") Console.Run("g_start");
                else if (e.Result.Text == "exit game") Console.Run("sh quitconfirm");
                else if (e.Result.Text == "pause game") IsPaused = true;
                else if (e.Result.Text == "resume game") IsPaused = false;
                else if (e.Result.Text == "sound off") MuteAllSounds = true;
                else if (e.Result.Text == "sound on") MuteAllSounds = false;
                else if (e.Result.Text == "music off") MuteMediaPlayer = true;
                else if (e.Result.Text == "music on") MuteMediaPlayer = false;
            }
        }
#endif

        float oldVolume;
        MediaState oldMediaState;
        protected override void OnDeactivated(object sender, EventArgs args)
        {
            oldVolume = SoundEffect.MasterVolume;
            SoundEffect.MasterVolume = 0;
            //MediaPlayer.IsMuted = true;
            oldMediaState = MediaPlayer.State;
            if (oldMediaState == MediaState.Playing)
                MediaPlayer.Pause();
            IsPaused = true;
            base.OnDeactivated(sender, args);
        }

        protected override void OnActivated(object sender, EventArgs args)
        {
            if (oldMediaState == MediaState.Playing) MediaPlayer.Resume();
            SoundEffect.MasterVolume = 1;// oldVolume;
            IsPaused = false;
            if (ActiveScreen == "game") Console.Run("sh ingamemenu");
            base.OnActivated(sender, args);
        }

        List<string> gameSongs = new List<string>{
            "song2", "song4", "song3"};
        int songIndex = 0;

        void MediaPlayer_MediaStateChanged(object sender, EventArgs e)
        {
            if (ActiveScreen == "game" && MediaPlayer.State != MediaState.Playing)
            {
                MediaPlayer.Play(GetSong(gameSongs[
                    songIndex = (songIndex + 1) % gameSongs.Count]));
            }
        }

        void e_playsongs(IList<string> args)
        {
            //MediaPlayer.Volume = 0.7f;
            songIndex = 0;
            MediaPlayer.Play(GetSong(gameSongs[songIndex++]));
            MediaPlayer.IsRepeating = false;
        }

        protected override void Behave(GameTime gameTime)
        {
            if (IsTapped(Keys.F11))
                Graphics.ToggleFullScreen();
            if (IsTapped(Keys.Pause))
                IsPaused = !IsPaused;

            base.Behave(gameTime);
        }

        protected override void Render(GameTime gameTime)
        {
            base.Render(gameTime);
            /*Write("Output: " + OutputResolution.X + "," + OutputResolution.Y + "\n" +
                "Game: " + GameWidth + "," + GameHeight + "\n" +
                "Preferred: " + Graphics.PreferredBackBufferWidth + "," + Graphics.PreferredBackBufferHeight + "\n" +
                "Screen: " + GraphicsDevice.DisplayMode.Width + "," + GraphicsDevice.DisplayMode.Height, Vector2.Zero);*/
            //trackHUD.Draw(gameTime);
#if KINECT
            if (Kinect != null && ActiveScreen == "game")
                SpriteBatch.Draw(GetTexture("kinectcolor"), new Rectangle(0, 0, 320, 240), 
                    GraphicsHelper.GetColorWithAlpha(Color.White, 0.25f));
#endif
        }

        protected override void UnloadContent()
        {
#if KINECT
            if (Kinect != null)
                Kinect.Uninitialize();
#endif
#if SPEECH
            if (Speech != null && Speech.Recognizing)
            {
                Speech.StopListening();
            }
#endif
            base.UnloadContent();
        }

        public override void AddScreens()
        {
            base.AddScreens();
            Screens["neatscreen"] = new NeatScreen(this);
            Screens["startscreen"] = new StartScreen(this);
            Screens["mainmenu"] = new MainMenuX(this);
            Screens["game"] = new RiverRaidGame(this);
            Screens["gameoverscreen"] = new GameOverScreen(this);
            Screens["creditsscreen"] = new CreditsScreen(this);
            Screens["optionsmenu"] = new OptionsMenuX(this);
        }

        Vector2 lastMousePos;
        float lastMouseFrame = 0;
        float maxMouseFrame = 30;
        protected override void DrawMouse(Vector2 pos)
        {
            if (lastMousePos == pos)
            {
                lastMouseFrame++;
            }
            else
                lastMouseFrame = 0;

            if (lastMouseFrame > maxMouseFrame)
            {
                MouseTint = Color.Lerp(MouseTint, Color.Transparent, 0.2f);
            }
            else
                MouseTint = Color.White;

            lastMousePos = pos;
            base.DrawMouse(pos);
        }
    }
}
